<!DOCTYPE html>
<html>
<head>
<title>Van der Waals Isotherms p-V Diagram</title>
</head>
<body>
<canvas id="myCanvas" width="500" height="450"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

// Style settings
ctx.strokeStyle = 'black';
ctx.fillStyle = 'black';
ctx.lineWidth = 2;
ctx.font = "18px Arial";
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';

const originX = 60;
const originY = 400;
const axisLenX = 400;
const axisLenY = 350;

// Helper function for drawing text with subscript
function drawTextWithSub(text, sub, x, y) {
    const mainFont = "italic 18px 'Times New Roman', serif";
    const subFont = "italic 12px 'Times New Roman', serif";
    
    ctx.font = mainFont;
    const textMetrics = ctx.measureText(text);
    const textWidth = textMetrics.width;
    ctx.fillText(text, x, y);

    ctx.font = subFont;
    ctx.fillText(sub, x + textWidth / 2 + 1, y + 18 / 4);
    
    // Reset font
    ctx.font = mainFont;
}

// Draw Axes
ctx.beginPath();
// p-axis (vertical)
ctx.moveTo(originX, originY);
ctx.lineTo(originX, originY - axisLenY);
ctx.lineTo(originX - 5, originY - axisLenY + 10);
ctx.moveTo(originX, originY - axisLenY);
ctx.lineTo(originX + 5, originY - axisLenY + 10);
// V-axis (horizontal)
ctx.moveTo(originX, originY);
ctx.lineTo(originX + axisLenX, originY);
ctx.lineTo(originX + axisLenX - 10, originY - 5);
ctx.moveTo(originX + axisLenX, originY);
ctx.lineTo(originX + axisLenX - 10, originY + 5);
ctx.stroke();

// Axis Labels
ctx.font = "italic 20px 'Times New Roman', serif";
ctx.fillText('p', originX - 25, originY - axisLenY);
ctx.fillText('V', originX + axisLenX + 15, originY);
ctx.font = "18px 'Times New Roman', serif";
ctx.fillText('O', originX - 15, originY + 15);


// Isotherm Coordinates
const pK_y = 200;
const VK_x = 190;
const p0_y = 280;
const V1_x = 130;
const Vg_x = 360;

// Draw Isotherms
ctx.lineWidth = 1.8;
ctx.beginPath();

// Critical Isotherm (T_K)
ctx.moveTo(VK_x - 70, 70);
ctx.bezierCurveTo(VK_x - 50, 160, VK_x - 20, 190, VK_x, pK_y);
ctx.bezierCurveTo(VK_x + 80, 220, VK_x + 150, 230, VK_x + 270, 260);
ctx.stroke();

// Second Isotherm
ctx.beginPath();
ctx.moveTo(VK_x - 80, 80);
ctx.bezierCurveTo(VK_x-30, 200, VK_x + 60, 215, VK_x + 270, 275);
ctx.stroke();

// Third Isotherm (with dip)
ctx.beginPath();
ctx.moveTo(VK_x - 90, 90);
ctx.bezierCurveTo(VK_x - 70, 170, VK_x - 40, 240, VK_x, 235); // dip down
ctx.bezierCurveTo(VK_x + 50, 230, VK_x + 70, 245, VK_x + 270, 290); // hump up and down
ctx.stroke();

// Main Isotherm (T)
ctx.beginPath();
ctx.moveTo(V1_x - 35, 100);
ctx.bezierCurveTo(V1_x, 220, 140, 320, 175, 310); // down to min
ctx.bezierCurveTo(220, 300, 260, 250, Vg_x, p0_y); // up to max and down to Vg
ctx.bezierCurveTo(Vg_x + 20, p0_y - 5, Vg_x + 50, p0_y + 10, Vg_x + 70, p0_y + 35); // tail
ctx.stroke();

// Dashed lines
ctx.setLineDash([5, 5]);
ctx.lineWidth = 1;

// Dashed lines for K
ctx.beginPath();
ctx.moveTo(originX, pK_y);
ctx.lineTo(VK_x, pK_y);
ctx.moveTo(VK_x, pK_y);
ctx.lineTo(VK_x, originY);
ctx.stroke();

// Dashed lines for T
ctx.beginPath();
ctx.moveTo(originX, p0_y);
ctx.lineTo(Vg_x, p0_y);
ctx.moveTo(V1_x, originY);
ctx.lineTo(V1_x, p0_y);
ctx.moveTo(Vg_x, originY);
ctx.lineTo(Vg_x, p0_y);
ctx.stroke();

// Reset line dash
ctx.setLineDash([]);

// Labels for points and lines
ctx.font = "italic 18px 'Times New Roman', serif";
ctx.textAlign = 'right';
drawTextWithSub('p', 'K', originX - 10, pK_y);
drawTextWithSub('p', '0', originX - 10, p0_y);

ctx.textAlign = 'center';
drawTextWithSub('V', '1', V1_x, originY + 20);
drawTextWithSub('V', 'K', VK_x, originY + 20);
drawTextWithSub('V', 'g', Vg_x, originY + 20);

// K point
ctx.font = "italic 18px 'Times New Roman', serif";
ctx.fillText('K', VK_x + 15, pK_y - 10);

// T_K label and pointer
const tk_label_x = 330;
const tk_label_y = 170;
drawTextWithSub('T', 'K', tk_label_x, tk_label_y);
ctx.beginPath();
ctx.lineWidth = 1.2;
ctx.moveTo(tk_label_x - 15, tk_label_y + 8);
ctx.lineTo(tk_label_x - 60, tk_label_y + 20);
// small tick
ctx.moveTo(tk_label_x - 15, tk_label_y + 8);
ctx.lineTo(tk_label_x - 20, tk_label_y - 1);
ctx.stroke();

// T label
ctx.font = "italic 18px 'Times New Roman', serif";
ctx.fillText('T', Vg_x + 65, 335);

// Caption
ctx.font = "20px 'KaiTi', 'SimSun'";
ctx.textAlign = 'center';
ctx.fillText('热图 4.3.1', canvas.width / 2, originY + 40);

</script>
</body>
</html>